//数据变化观察者，同时也是dispatcher的订阅者
;
(function(win) {
    function Watcher(vm, expr, cb) {
        this.vm = vm;
        this.expr = expr;
        this.cb = cb;
        this.dispatchers = {};
        this.value = this.get();
    }

    Watcher.prototype = {
        update: function() {
            this.run();
        },
        run: function() {
            var oldValue = this.value;
            this.value = this.get();
            if (oldValue !== this.value) {
                this.cb.call(this.vm, this.value, oldValue);
            }
        },
        addDispatcher: function(dispatcher) {
            if (!Object.hasOwnProperty(this.dispatchers, dispatcher.uuid)) {
                dispatcher.addSub(this);
                this.dispatchers[dispatcher.uuid] = dispatcher;
            }
        },
        get: function() {
            var val = this.vm;
            Dispatcher.target = this;
            if (this.expr) {
                val = getVMValue.call(this);
            }
            Dispatcher.target = null;
            return val;
        }
    };

    function getVMValue() {
        var val = this.vm._data;
        this.expr.split(".").forEach(function(ex) {
            val = val[ex];
        });
        return val;
    }
    win.Watcher = Watcher;
})(window);